home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / JScrollPane.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  37.1 KB  |  1,189 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)JScrollPane.java    1.57 98/08/28
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package javax.swing;
  16.  
  17. import javax.swing.plaf.*;
  18. import javax.swing.border.*;
  19. import javax.swing.event.*;
  20. import javax.accessibility.*;
  21.  
  22. import java.awt.Component;
  23. import java.awt.Graphics;
  24. import java.awt.Rectangle;
  25. import java.awt.Insets;
  26. import java.awt.Color;
  27. import java.awt.LayoutManager;
  28.  
  29. import java.io.ObjectOutputStream;
  30. import java.io.ObjectInputStream;
  31. import java.io.IOException;
  32.  
  33.  
  34. /**
  35.  * A specialized container that manages a viewport, optional
  36.  * vertical and horizontal scrollbars, and optional row and
  37.  * column heading viewports.
  38.  * <p>
  39.  * <TABLE ALIGN="RIGHT" BORDER="0">
  40.  *    <TR>
  41.  *    <TD ALIGN="CENTER">
  42.  *      <P ALIGN="CENTER"><IMG SRC="doc-files/JScrollPane-1.gif" WIDTH="256" HEIGHT="248" ALIGN="BOTTOM" BORDER="0">
  43.  *    </TD>
  44.  *    </TR>
  45.  * </TABLE>
  46.  * The JViewPort provides a window, or "viewport" onto a data 
  47.  * source -- for example, a text file. That data source is the 
  48.  * "scrollable client" (aka data model) displayed by the 
  49.  * JViewport view. A JScrollPane basically consists of JScrollBars, a JViewport, 
  50.  * and the wiring between them, as shown in the diagram at right. 
  51.  * <p>
  52.  * In addition to the scroll bars and viewport, a JScrollPane can have a
  53.  * column header and a row header. Each of these is a JViewport object that
  54.  * you specify with <code>setRowHeaderView</code>, and <code>setColumnHeaderView</code>.
  55.  * The column header viewport automatically scrolls left and right, tracking
  56.  * the left-right scrolling of the main viewport. (It never scrolls vertically,
  57.  * however.) The row header acts in a similar fashion.
  58.  * <p>
  59.  * By default, the corners are empty. You can put a component into a corner using 
  60.  * <code>setCorner</code>, in case you there is some function or decoration you
  61.  * would like to add to the scroll pane. The size of corner components is
  62.  * entirely determined by the size of the headers and scroll bars that surround them.
  63.  * <p>
  64.  * To add a border around the main viewport, you can use <code>setViewportBorder</code>. 
  65.  * (Of course, you can also add a border around the whole scroll pane using
  66.  * <code>setBorder</code>.)
  67.  * <p>
  68.  * For the keyboard keys used by this component in the standard Look and
  69.  * Feel (L&F) renditions, see the
  70.  * <a href="doc-files/Key-Index.html#JScrollPane">JScrollPane</a> 
  71.  * key assignments.
  72.  * <p>
  73.  * <strong>Warning:</strong>
  74.  * Serialized objects of this class will not be compatible with
  75.  * future Swing releases.  The current serialization support is appropriate
  76.  * for short term storage or RMI between applications running the same
  77.  * version of Swing.  A future release of Swing will provide support for
  78.  * long term persistence.
  79.  *
  80.  * @see JScrollBar
  81.  * @see JViewport
  82.  * @see #setViewportView
  83.  * @see #setRowHeaderView
  84.  * @see #setColumnHeaderView
  85.  * @see #setCorner
  86.  * @see #setViewportBorder
  87.  * 
  88.  * @beaninfo
  89.  *     attribute: isContainer true
  90.  *     attribute: containerDelegate getViewport
  91.  *   description: A specialized container that manages a viewport, optional scrollbars and headers
  92.  *
  93.  * @version 1.57 08/28/98
  94.  * @author Hans Muller
  95.  */
  96. public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible
  97. {
  98.     private Border viewportBorder;
  99.  
  100.     /**
  101.      * @see #getUIClassID
  102.      * @see #readObject
  103.      */
  104.     private static final String uiClassID = "ScrollPaneUI";
  105.  
  106.     /** 
  107.      * The display policy for the vertical scrollbar.
  108.      * The default is JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED.
  109.      * @see #setVerticalScrollBarPolicy
  110.      */
  111.     protected int verticalScrollBarPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
  112.  
  113.  
  114.     /**
  115.      * The display policy for the horizontal scrollbar.
  116.      * The default is JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED.
  117.      * @see #setHorizontalScrollBarPolicy
  118.      */
  119.     protected int horizontalScrollBarPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
  120.  
  121.  
  122.     /** 
  123.      * The scrollpanes viewport child.  Default is an empty JViewport.
  124.      * @see #setViewport
  125.      */
  126.     protected JViewport viewport;
  127.  
  128.  
  129.     /**
  130.      * The scrollpane's vertical scrollbar child.  Default is a JScrollBar.
  131.      * @see #setVerticalScrollBar
  132.      */
  133.     protected JScrollBar verticalScrollBar;
  134.  
  135.  
  136.     /**
  137.      * The scrollpane's horizontal scrollbar child.  Default is a JScrollBar.
  138.      * @see #setHorizontalScrollBar
  139.      */
  140.     protected JScrollBar horizontalScrollBar;
  141.  
  142.  
  143.     /** 
  144.      * The row header child.  Default is null.
  145.      * @see #setRowHeader
  146.      */
  147.     protected JViewport rowHeader;
  148.  
  149.  
  150.     /** 
  151.      * The column header child.  Default is null.
  152.      * @see #setColumnHeader
  153.      */
  154.     protected JViewport columnHeader;
  155.  
  156.  
  157.     /**
  158.      * The component to display in the lower left corner.  Default is null.
  159.      * @see #setCorner
  160.      */
  161.     protected Component lowerLeft;
  162.  
  163.  
  164.     /**
  165.      * The component to display in the lower right corner.  Default is null.
  166.      * @see #setCorner
  167.      */
  168.     protected Component lowerRight;
  169.  
  170.  
  171.     /**
  172.      * The component to display in the upper left corner.  Default is null.
  173.      * @see #setCorner
  174.      */
  175.     protected Component upperLeft;
  176.  
  177.  
  178.     /**
  179.      * The component to display in the upper right corner.  Default is null.
  180.      * @see #setCorner
  181.      */
  182.     protected Component upperRight;
  183.  
  184.  
  185.     /**
  186.      * Create a JScrollPane that displays the view component in a viewport
  187.      * whose view position can be controlled with a pair of scrollbars.
  188.      * The scrollbar policies specify when the scrollbars are displayed, 
  189.      * e.g. if <code>vsbPolicy</code> is VERTICAL_SCROLLBAR_AS_NEEDED</code>
  190.      * then the vertical scrollbar only appears if the view doesn't fit
  191.      * vertically. The available policies settings are listed at 
  192.      * {@link #setVerticalScrollBarPolicy} and {@link #setHorizontalScrollBarPolicy}.
  193.      * 
  194.      * @see #setViewportView
  195.      * 
  196.      * @param view the Component to display in the scrollpanes viewport
  197.      * @param vsbPolicy an int that specifies the vertical scrollbar policy
  198.      * @param hsbPolicy an int that specifies the horizontal scrollbar policy
  199.      */
  200.     public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) 
  201.     {
  202.     setLayout(new ScrollPaneLayout.UIResource());
  203.         setVerticalScrollBarPolicy(vsbPolicy);
  204.         setHorizontalScrollBarPolicy(hsbPolicy);
  205.     setViewport(createViewport());
  206.     setVerticalScrollBar(createVerticalScrollBar());
  207.     setHorizontalScrollBar(createHorizontalScrollBar());
  208.     if (view != null) {
  209.         setViewportView(view);
  210.     }
  211.         updateUI();
  212.     }
  213.  
  214.  
  215.     /**
  216.      * Create a JScrollPane that displays the contents of the specified
  217.      * component, where both horizontal and vertical scrollbars appear
  218.      * whenever the component's contents are larger than the view.
  219.      * 
  220.      * @see #setViewportView
  221.      * @param view the Component to display in the scrollpanes viewport
  222.      */
  223.     public JScrollPane(Component view) {
  224.         this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
  225.     }
  226.  
  227.  
  228.     /**
  229.      * Create an empty (no viewport view) JScrollPane with specified 
  230.      * scrollbar policies. The available policies settings are listed at 
  231.      * {@link #setVerticalScrollBarPolicy} and {@link #setHorizontalScrollBarPolicy}.
  232.      * 
  233.      * @see #setViewportView
  234.      * 
  235.      * @param vsbPolicy an int that specifies the vertical scrollbar policy
  236.      * @param hsbPolicy an int that specifies the horizontal scrollbar policy
  237.      */
  238.     public JScrollPane(int vsbPolicy, int hsbPolicy) {
  239.         this(null, vsbPolicy, hsbPolicy);
  240.     }
  241.  
  242.  
  243.     /**
  244.      * Create an empty (no viewport view) JScrollPane where both horizontal and vertical 
  245.      * scrollbars appear when needed.
  246.      */
  247.     public JScrollPane() {
  248.         this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
  249.     }
  250.  
  251.  
  252.     /**
  253.      * Returns the L&F object that renders this component.
  254.      *
  255.      * @return the ScrollPaneUI object that renders this component
  256.      * @see #setUI
  257.      */
  258.     public ScrollPaneUI getUI() {
  259.         return (ScrollPaneUI)ui;
  260.     }
  261.  
  262.  
  263.     /**
  264.      * Sets the ScrollPaneUI object that provides the look and feel for
  265.      * this component.
  266.      *
  267.      * @param ui the ScrollPaneUI L&F object
  268.      * @see #getUI
  269.      */
  270.     public void setUI(ScrollPaneUI ui) {
  271.         super.setUI(ui);
  272.     }
  273.  
  274.  
  275.     /**
  276.      * To be called when the default look and feel changes.
  277.      * Replaces the current ScrollPaneUI object with a version 
  278.      * from the current default LookAndFeel.
  279.      *
  280.      * @see JComponent#updateUI
  281.      * @see UIManager#getUI
  282.      */
  283.     public void updateUI() {
  284.         setUI((ScrollPaneUI)UIManager.getUI(this));
  285.     }
  286.  
  287.  
  288.     /**
  289.      * Returns the key used to look up the ScrollPaneUI class that provides
  290.      * the look and feel for JScrollPane.
  291.      * 
  292.      * @return "ScrollPaneUI"
  293.      * @see JComponent#getUIClassID
  294.      * @see UIDefaults#getUI
  295.      * 
  296.      * @beaninfo
  297.      *    hidden: true
  298.      */
  299.     public String getUIClassID() {
  300.         return uiClassID;
  301.     }
  302.  
  303.  
  304.  
  305.     /** 
  306.      * Sets the layout manager for this JScrollPane. This method overrides 
  307.      * setLayout in java.awt.Container to ensure that only LayoutManagers which
  308.      * are subclasses of ScrollPaneLayout can be used in a JScrollPane.
  309.      * 
  310.      * @param layout the specified layout manager
  311.      * @exception ClassCastException if layout is not a ScrollPaneLayout
  312.      * @see java.awt.Container#getLayout
  313.      * @see java.awt.Container#setLayout
  314.      * 
  315.      * @beaninfo
  316.      *    hidden: true
  317.      */
  318.     public void setLayout(LayoutManager layout) {
  319.         if ((layout == null) || (layout instanceof ScrollPaneLayout)) {
  320.             super.setLayout(layout);
  321.         }
  322.     else {
  323.         String s = "layout of JScrollPane must be a ScrollPaneLayout";
  324.         throw new ClassCastException(s);
  325.     }
  326.     }
  327.  
  328.  
  329.     /**
  330.      * Returns true if this component paints every pixel
  331.      * in its range. (In other words, it does not have a transparent
  332.      * background or foreground.)
  333.      *
  334.      * @return The value of the opaque property
  335.      * @see JComponent#isOpaque
  336.      */
  337.     public boolean isOpaque() {
  338.         JViewport viewport;
  339.         Component view;
  340.         if( (viewport = getViewport()) != null    && 
  341.             ((view = viewport.getView()) != null) &&
  342.             ((view instanceof JComponent) && ((JComponent)view).isOpaque())) {
  343.             if(((JComponent)view).getWidth()  >= viewport.getWidth() && 
  344.                ((JComponent)view).getHeight() >= viewport.getHeight())
  345.                 return true;
  346.         }
  347.         return false;
  348.     }
  349.  
  350.  
  351.     /** 
  352.      * Calls to revalidate() on any descendant of this JScrollPane, e.g. 
  353.      * the viewports view, will cause a request to be queued that
  354.      * will validate the JScrollPane and all its descendants.
  355.      * 
  356.      * @return true
  357.      * @see JComponent#revalidate
  358.      * 
  359.      * @beaninfo
  360.      *    hidden: true
  361.      */
  362.     public boolean isValidateRoot() {
  363.         return true;
  364.     }
  365.  
  366.  
  367.     /**
  368.      * Returns the vertical scroll bar policy value.
  369.      * @return the vertical scrollbar policy
  370.      * @see #setVerticalScrollBarPolicy
  371.      */
  372.     public int getVerticalScrollBarPolicy() {
  373.         return verticalScrollBarPolicy;
  374.     }
  375.  
  376.  
  377.     /**
  378.      * Determines when the vertical scrollbar appears in the scrollpane. 
  379.      * Legal values are:
  380.      * <ul>
  381.      * <li>JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
  382.      * <li>JScrollPane.VERTICAL_SCROLLBAR_NEVER
  383.      * <li>JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
  384.      * </ul>
  385.      *
  386.      * @see #getVerticalScrollBarPolicy
  387.      * 
  388.      * @beaninfo
  389.      *   preferred: true
  390.      *       bound: true
  391.      * description: The scrollpane vertical scrollbar policy
  392.      *        enum: VERTICAL_SCROLLBAR_AS_NEEDED JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
  393.      *              VERTICAL_SCROLLBAR_NEVER JScrollPane.VERTICAL_SCROLLBAR_NEVER
  394.      *              VERTICAL_SCROLLBAR_ALWAYS JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
  395.      */
  396.     public void setVerticalScrollBarPolicy(int policy) {
  397.     switch (policy) {
  398.     case VERTICAL_SCROLLBAR_AS_NEEDED:
  399.     case VERTICAL_SCROLLBAR_NEVER:
  400.     case VERTICAL_SCROLLBAR_ALWAYS:
  401.         break;
  402.     default:
  403.         throw new IllegalArgumentException("invalid verticalScrollBarPolicy");
  404.     }
  405.     int old = verticalScrollBarPolicy;
  406.     verticalScrollBarPolicy = policy;
  407.     firePropertyChange("verticalScrollBarPolicy", old, policy);
  408.     }
  409.  
  410.  
  411.     /**
  412.      * Returns the horizontal scroll bar policy value.
  413.      * @return the horizontal scrollbar policy.
  414.      * @see #setHorizontalScrollBarPolicy
  415.      */
  416.     public int getHorizontalScrollBarPolicy() {
  417.     return horizontalScrollBarPolicy;
  418.     }
  419.  
  420.  
  421.     /**
  422.      * Determines when the horizontal scrollbar appears in the scrollpane. 
  423.      * The options are:<ul>
  424.      * <li>JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
  425.      * <li>JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
  426.      * <li>JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
  427.      * </ul>
  428.      * 
  429.      * @see #getHorizontalScrollBarPolicy
  430.      *
  431.      * @beaninfo
  432.      *   preferred: true
  433.      *       bound: true
  434.      * description: The scrollpane scrollbar policy
  435.      *        enum: HORIZONTAL_SCROLLBAR_AS_NEEDED JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
  436.      *              HORIZONTAL_SCROLLBAR_NEVER JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
  437.      *              HORIZONTAL_SCROLLBAR_ALWAYS JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
  438.      */
  439.     public void setHorizontalScrollBarPolicy(int policy) {
  440.     switch (policy) {
  441.     case HORIZONTAL_SCROLLBAR_AS_NEEDED:
  442.     case HORIZONTAL_SCROLLBAR_NEVER:
  443.     case HORIZONTAL_SCROLLBAR_ALWAYS:
  444.         break;
  445.     default:
  446.         throw new IllegalArgumentException("invalid horizontalScrollBarPolicy");
  447.     }
  448.     int old = horizontalScrollBarPolicy;
  449.     horizontalScrollBarPolicy = policy;
  450.     firePropertyChange("horizontalScrollBarPolicy", old, policy);
  451.     }
  452.  
  453.  
  454.     /**
  455.      * Returns the value of the viewportBorder property.
  456.      *
  457.      * @return the Border object that surrounds the viewport
  458.      * @see #setViewportBorder
  459.      */
  460.     public Border getViewportBorder() {
  461.         return viewportBorder;
  462.     }
  463.  
  464.  
  465.     /**
  466.      * Add a border around the viewport.  Note that the border isn't
  467.      * set on the viewport directly, JViewport doesn't support the
  468.      * JComponent border property.  Similarly setting the JScrollPanes
  469.      * viewport doesn't effect the viewportBorder property.
  470.      * <p>
  471.      * The default value of this property is computed by the look
  472.      * and feel implementation.
  473.      *
  474.      * @see #getViewportBorder
  475.      * @see #setViewport
  476.      *
  477.      * @beaninfo
  478.      *   preferred: true
  479.      *       bound: true
  480.      * description: The border around the viewport.
  481.      */
  482.     public void setViewportBorder(Border viewportBorder) {
  483.         Border oldValue = this.viewportBorder;
  484.         this.viewportBorder = viewportBorder;
  485.         firePropertyChange("viewportBorder", oldValue, viewportBorder);
  486.     }
  487.  
  488.  
  489.     /**
  490.      * Returns the bounds of the viewport border.
  491.      *
  492.      * @return a Rectangle object specifying the viewport border
  493.      */
  494.     public Rectangle getViewportBorderBounds()
  495.     {
  496.     Rectangle borderR = new Rectangle(getSize());
  497.  
  498.     Insets insets = getInsets();
  499.     borderR.x = insets.left;
  500.     borderR.y = insets.top;
  501.     borderR.width -= insets.left + insets.right;
  502.     borderR.height -= insets.top + insets.bottom;
  503.  
  504.  
  505.     /* If there's a visible column header remove the space it 
  506.      * needs from the top of borderR.  
  507.      */
  508.  
  509.     JViewport colHead = getColumnHeader();
  510.     if ((colHead != null) && (colHead.isVisible())) {
  511.         int colHeadHeight = colHead.getHeight();
  512.         borderR.y += colHeadHeight;
  513.         borderR.height -= colHeadHeight;
  514.     }
  515.  
  516.     /* If there's a visible row header remove the space it needs
  517.      * from the left of borderR.  
  518.      */
  519.  
  520.     JViewport rowHead = getRowHeader();
  521.     if ((rowHead != null) && (rowHead.isVisible())) {
  522.         int rowHeadWidth = rowHead.getWidth();
  523.         borderR.x += rowHeadWidth;
  524.         borderR.width -= rowHeadWidth;
  525.     }
  526.  
  527.     /* If there's a visible vertical scrollbar remove the space it needs
  528.      * from the width of borderR.  
  529.      */
  530.     JScrollBar vsb = getVerticalScrollBar();
  531.     if ((vsb != null) && (vsb.isVisible())) {
  532.         borderR.width -= vsb.getWidth();
  533.     }
  534.  
  535.     /* If there's a visible horizontal scrollbar remove the space it needs
  536.      * from the height of borderR.  
  537.      */
  538.     JScrollBar hsb = getHorizontalScrollBar();
  539.     if ((hsb != null) && (hsb.isVisible())) {
  540.         borderR.height -= hsb.getHeight();
  541.     }
  542.  
  543.     return borderR;
  544.     }
  545.  
  546.  
  547.     /**
  548.      * By default JScrollPane creates scrollbars that are instances
  549.      * of this class.  Scrollbar overrides the getUnitIncrement
  550.      * and getBlockIncrement methods so that, if the viewports view is 
  551.      * a Scrollable, the view is asked to compute these values. Unless
  552.      * the unit/block increment have been explicitly set.
  553.      * <p>
  554.      * <strong>Warning:</strong>
  555.      * Serialized objects of this class will not be compatible with
  556.      * future Swing releases.  The current serialization support is appropriate
  557.      * for short term storage or RMI between applications running the same
  558.      * version of Swing.  A future release of Swing will provide support for
  559.      * long term persistence.
  560.      *
  561.      * @see Scrollable
  562.      * @see JScrollPane#createVerticalScrollBar
  563.      * @see JScrollPane#createHorizontalScrollBar
  564.      */
  565.     protected class ScrollBar extends JScrollBar implements UIResource
  566.     {
  567.     /** 
  568.          * Set to true when the unit increment has been explicitly set.
  569.      * If this is false the viewports view is obtained and if it
  570.      * is an instance of Scrollable the unit increment from it is used.
  571.      */
  572.     private boolean unitIncrementSet;
  573.     /** 
  574.          * Set to true when the block increment has been explicitly set.
  575.      * If this is false the viewports view is obtained and if it
  576.      * is an instance of Scrollable the block increment from it is used.
  577.      */
  578.     private boolean blockIncrementSet;
  579.  
  580.         /**
  581.          * Create a scrollbar with the specified orientation, where the options
  582.          * are:<ul>
  583.          * <li>JScrollPane.VERTICAL_SCROLLBAR
  584.          * <li>JScrollPane.HORIZONTAL_SCROLLBAR
  585.          * </ul>
  586.          *
  587.          * @param orientation  an int specifying the orientation
  588.          */
  589.         public ScrollBar(int orientation) {
  590.             super(orientation);
  591.         }
  592.  
  593.     /**
  594.      * Messages super to set the value, and resets the
  595.      * <code>unitIncrementSet</code> instance variable to true.
  596.      */
  597.     public void setUnitIncrement(int unitIncrement) { 
  598.         unitIncrementSet = true;
  599.         super.setUnitIncrement(unitIncrement);
  600.     }
  601.  
  602.         /**
  603.          * If the viewports view is a Scrollable then ask the view
  604.          * to compute the unit increment.  Otherwise return
  605.          * super.getUnitIncrement().
  606.          * 
  607.          * @see Scrollable#getScrollableUnitIncrement
  608.          */
  609.         public int getUnitIncrement(int direction) {
  610.             JViewport vp = getViewport();
  611.             if (!unitIncrementSet && (vp != null) &&
  612.         (vp.getView() instanceof Scrollable)) {
  613.                 Scrollable view = (Scrollable)(vp.getView());
  614.                 Rectangle vr = vp.getViewRect();
  615.                 return view.getScrollableUnitIncrement(vr, getOrientation(), direction);
  616.             }
  617.             else {
  618.                 return super.getUnitIncrement(direction);
  619.             }
  620.         }
  621.  
  622.     /**
  623.      * Messages super to set the value, and resets the
  624.      * <code>blockIncrementSet</code> instance variable to true.
  625.      */
  626.     public void setBlockIncrement(int blockIncrement) { 
  627.         blockIncrementSet = true;
  628.         super.setBlockIncrement(blockIncrement);
  629.     }
  630.  
  631.         /**
  632.          * If the viewports view is a Scrollable then ask the
  633.          * view to compute the block increment.  Otherwise
  634.          * the blockIncrement equals the viewports width
  635.          * or height.  If there's no viewport reuurn 
  636.          * super.getBlockIncrement().
  637.          * 
  638.          * @see Scrollable#getScrollableBlockIncrement
  639.          */
  640.         public int getBlockIncrement(int direction) {
  641.             JViewport vp = getViewport();
  642.             if (blockIncrementSet || vp == null) {
  643.                 return super.getBlockIncrement(direction);
  644.             }
  645.             else if (vp.getView() instanceof Scrollable) {
  646.                 Scrollable view = (Scrollable)(vp.getView());
  647.                 Rectangle vr = vp.getViewRect();
  648.                 return view.getScrollableBlockIncrement(vr, getOrientation(), direction);
  649.             }
  650.             else if (getOrientation() == VERTICAL) {
  651.                 return vp.getExtentSize().height;
  652.             }
  653.             else {
  654.                 return vp.getExtentSize().width;
  655.             }
  656.         }
  657.  
  658.     }
  659.  
  660.  
  661.     /**
  662.      * Used by ScrollPaneUI implementations to create the horizontal
  663.      * scrollbar.  Returns a JScrollPane.ScrollBar by default.  Subclasses
  664.      * may override this method to force ScrollPaneUI implementations to
  665.      * use a JScrollBar subclass.
  666.      *
  667.      * @return a JScrollBar with a horizontal orientation
  668.      * @see JScrollBar
  669.      */
  670.     public JScrollBar createHorizontalScrollBar() {
  671.         return new ScrollBar(JScrollBar.HORIZONTAL);
  672.     }
  673.  
  674.  
  675.     /**
  676.      * Returns the horizontal scroll bar.
  677.      * @return the scrollbar that controls the viewports horizontal view position
  678.      * @see #setHorizontalScrollBar
  679.      */
  680.     public JScrollBar getHorizontalScrollBar() {
  681.         return horizontalScrollBar;
  682.     }
  683.  
  684.     
  685.     /**
  686.      * Add the scrollbar that controls the viewports horizontal view position
  687.      * to the scrollpane.  This is usually unneccessary, JScrollPane creates
  688.      * horizontal and vertical scrollbars by default.
  689.      * 
  690.      * @see #createHorizontalScrollBar
  691.      * @see #getHorizontalScrollBar
  692.      * 
  693.      * @beaninfo
  694.      *        expert: true
  695.      *         bound: true
  696.      *   description: The horizontal scrollbar.
  697.      */
  698.     public void setHorizontalScrollBar(JScrollBar horizontalScrollBar) {
  699.     JScrollBar old = getHorizontalScrollBar();
  700.     this.horizontalScrollBar = horizontalScrollBar;
  701.     add(horizontalScrollBar, HORIZONTAL_SCROLLBAR);
  702.     firePropertyChange("horizontalScrollBar", old, horizontalScrollBar);
  703.     }
  704.  
  705.  
  706.     /**
  707.      * Used by ScrollPaneUI implementations to create the vertical
  708.      * scrollbar.  Returns a JScrollPane.ScrollBar by default.  Subclasses
  709.      * may override this method to force ScrollPaneUI implementations to
  710.      * use a JScrollBar subclass.
  711.      *
  712.      * @return a JScrollBar with a vertical orientation
  713.      * @see JScrollBar
  714.      */
  715.     public JScrollBar createVerticalScrollBar() {
  716.         return new ScrollBar(JScrollBar.VERTICAL);
  717.     }
  718.  
  719.  
  720.     /**
  721.      * Returns the vertical scroll bar.
  722.      * @return the scrollbar that controls the viewports vertical view position
  723.      * @see #setVerticalScrollBar
  724.      */
  725.     public JScrollBar getVerticalScrollBar() {
  726.     return verticalScrollBar;
  727.     }
  728.  
  729.  
  730.     /**
  731.      * Add the scrollbar that controls the viewports vertical view position
  732.      * to the scrollpane.  This is usually unneccessary, JScrollPane creates
  733.      * vertical and vertical scrollbars by default.
  734.      * 
  735.      * @see #createVerticalScrollBar
  736.      * @see #getVerticalScrollBar
  737.      * 
  738.      * @beaninfo
  739.      *        expert: true
  740.      *         bound: true
  741.      *   description: The vertical scrollbar.
  742.      */
  743.     public void setVerticalScrollBar(JScrollBar verticalScrollBar) {
  744.     JScrollBar old = getVerticalScrollBar();
  745.     this.verticalScrollBar = verticalScrollBar;
  746.     add(verticalScrollBar, VERTICAL_SCROLLBAR);
  747.     firePropertyChange("verticalScrollBar", old, verticalScrollBar);
  748.     }
  749.  
  750.  
  751.     /**
  752.      * Returns a new JViewport by default.  Used to create the
  753.      * viewport (as needed) in <code>setViewportView</code>,
  754.      * <code>setRowHeaderView</code>, and <code>setColumnHeaderView</code>.
  755.      * Subclasses may override this method to return a subclass of JViewport.
  756.      *
  757.      * @return a JViewport
  758.      */
  759.     protected JViewport createViewport() {
  760.         return new JViewport();
  761.     }
  762.  
  763.  
  764.     /**
  765.      * Returns the current JViewport.
  766.      *
  767.      * @see #setViewport
  768.      * @return the JViewport currently in use
  769.      */
  770.     public JViewport getViewport() {
  771.         return viewport;
  772.     }
  773.  
  774.     
  775.     /**
  776.      * Remove the old viewport (if there is one), force the
  777.      * viewPosition of the new viewport to be in the +x,+y quadrant,
  778.      * sync up the row and column headers (if there are any) with the
  779.      * new viewport, and finally sync the scrollbars and
  780.      * headers with the new viewport.
  781.      * <p>
  782.      * Most applications will find it more convenient to use setViewportView
  783.      * to add a viewport and a view to the scrollpane.
  784.      * 
  785.      * @see #createViewport
  786.      * @see #getViewport
  787.      * @see #setViewportView
  788.      * 
  789.      * @beaninfo
  790.      *       expert: true
  791.      *        bound: true
  792.      *  description: The viewport child for this scrollpane
  793.      * 
  794.      */
  795.     public void setViewport(JViewport viewport) {
  796.     JViewport old = getViewport();
  797.     this.viewport = viewport;
  798.     if (viewport != null) {
  799.         add(viewport, VIEWPORT);
  800.     }
  801.     else if (old != null) {
  802.         remove(old);
  803.     }
  804.     firePropertyChange("viewport", old, viewport);
  805.  
  806.     if (accessibleContext != null) {
  807.         ((AccessibleJScrollPane)accessibleContext).resetViewPort();
  808.     }
  809.     }
  810.  
  811.  
  812.     /**
  813.      * Creates a viewport if neccessary and then sets its view.  Applications
  814.      * that don't provide the view directly to the JScrollPane constructor
  815.      * should use this method to specify the scrollable child that's going
  816.      * to be displayed in the scrollpane, e.g.:
  817.      * <pre>
  818.      * JScrollPane scrollpane = new JScrollPane();
  819.      * scrollpane.setViewportView(myBigComponentToScroll);
  820.      * </pre>
  821.      * Applications should not add children directly to the scrollpane.
  822.      *
  823.      * @param view the Component to add to the viewport
  824.      * @see #setViewport
  825.      * @see JViewport#setView
  826.      */
  827.     public void setViewportView(Component view) {
  828.         if (getViewport() == null) {
  829.             setViewport(createViewport());
  830.         }
  831.         getViewport().setView(view);
  832.     }
  833.  
  834.  
  835.  
  836.     /**
  837.      * Returns the row header.
  838.      * @return the JViewport for the row header
  839.      * @see #setRowHeader
  840.      */
  841.     public JViewport getRowHeader() {
  842.         return rowHeader;
  843.     }
  844.  
  845.  
  846.     /**
  847.      * If an old rowHeader exists, remove it.  If the new rowHeader
  848.      * isn't null, sync the y coordinate of the its viewPosition with
  849.      * the viewport (if there is one) and then add it to the ScrollPane.
  850.      * <p>
  851.      * Most applications will find it more convenient to use setRowHeaderView
  852.      * to add a row header component and its viewport to the scrollpane.
  853.      * 
  854.      * @see #getRowHeader
  855.      * @see #setRowHeaderView
  856.      * 
  857.      * @beaninfo
  858.      *        bound: true
  859.      *       expert: true
  860.      *  description: The row header child for this scrollpane
  861.      */
  862.     public void setRowHeader(JViewport rowHeader) {
  863.     JViewport old = getRowHeader();
  864.     this.rowHeader = rowHeader;    
  865.     if (rowHeader != null) {
  866.         add(rowHeader, ROW_HEADER);
  867.     }
  868.     else if (old != null) {
  869.         remove(old);
  870.     }
  871.     firePropertyChange("rowHeader", old, rowHeader);
  872.     }
  873.  
  874.  
  875.     /**
  876.      * Creates a row-header viewport if neccessary, sets
  877.      * its view and then adds the row-header viewport
  878.      * to the scrollpane.  For example:
  879.      * <pre>
  880.      * JScrollPane scrollpane = new JScrollPane();
  881.      * scrollpane.setViewportView(myBigComponentToScroll);
  882.      * scrollpane.setRowHeaderView(myBigComponentsRowHeader);
  883.      * </pre>
  884.      *
  885.      * @see #setRowHeader
  886.      * @see JViewport#setView
  887.      * @param view the Component to display as the row header
  888.      */
  889.     public void setRowHeaderView(Component view) {
  890.         if (getRowHeader() == null) {
  891.             setRowHeader(createViewport());
  892.         }
  893.         getRowHeader().setView(view);
  894.     }
  895.  
  896.  
  897.  
  898.     /**
  899.      * Returns the column header.
  900.      * @return a JViewport object for the column header 
  901.      * @see #setColumnHeader
  902.      */
  903.     public JViewport getColumnHeader() {
  904.         return columnHeader;
  905.     }
  906.  
  907.  
  908.     /**
  909.      * If an old columnHeader exists, remove it.  If the new columnHeader
  910.      * isn't null, sync the x coordinate of the its viewPosition with
  911.      * the viewport (if there is one) and then add it to the ScrollPane.
  912.      * <p>
  913.      * Most applications will find it more convenient to use setRowHeaderView
  914.      * to add a row header component and its viewport to the scrollpane.
  915.      * 
  916.      * @see #getColumnHeader
  917.      * @see #setColumnHeaderView
  918.      * 
  919.      * @beaninfo
  920.      *        bound: true
  921.      *  description: The column header child for this scrollpane
  922.      */
  923.     public void setColumnHeader(JViewport columnHeader) {
  924.     JViewport old = getColumnHeader();
  925.     this.columnHeader = columnHeader;    
  926.     if (columnHeader != null) {
  927.         add(columnHeader, COLUMN_HEADER);
  928.     }
  929.     else if (old != null) {
  930.         remove(columnHeader);
  931.     }
  932.     firePropertyChange("columnHeader", old, columnHeader);
  933.     }
  934.  
  935.  
  936.  
  937.     /**
  938.      * Creates a column-header viewport if neccessary, sets
  939.      * its view and then adds the column-header viewport
  940.      * to the scrollpane.  For example:
  941.      * <pre>
  942.      * JScrollPane scrollpane = new JScrollPane();
  943.      * scrollpane.setViewportView(myBigComponentToScroll);
  944.      * scrollpane.setColumnHeaderView(myBigComponentsColumnHeader);
  945.      * </pre>
  946.      * 
  947.      * @see #setColumnHeader
  948.      * @see JViewport#setView
  949.      * 
  950.      * @param view the Component to display as the column header
  951.      */
  952.     public void setColumnHeaderView(Component view) {
  953.         if (getColumnHeader() == null) {
  954.             setColumnHeader(createViewport());
  955.         }
  956.         getColumnHeader().setView(view);
  957.     }
  958.  
  959.  
  960.     /**
  961.      * Returns the component at the specified corner. The
  962.      * <code>key</code> value specifying the corner is one of:
  963.      * <ul>
  964.      * <li>JScrollPane.LOWER_LEFT_CORNER
  965.      * <li>JScrollPane.LOWER_RIGHT_CORNER
  966.      * <li>JScrollPane.UPPER_LEFT_CORNER
  967.      * <li>JScrollPane.UPPER_RIGHT_CORNER
  968.      * </ul>
  969.      *
  970.      * @see #setCorner
  971.      * @return the Component at the specified corner
  972.      */
  973.     public Component getCorner(String key) {
  974.     if (key.equals(LOWER_LEFT_CORNER)) {
  975.         return lowerLeft;
  976.     }
  977.     else if (key.equals(LOWER_RIGHT_CORNER)) {
  978.         return lowerRight;
  979.     }
  980.     else if (key.equals(UPPER_LEFT_CORNER)) {
  981.         return upperLeft;
  982.     }
  983.     else if (key.equals(UPPER_RIGHT_CORNER)) {
  984.         return upperRight;
  985.     }
  986.     else {
  987.         return null;
  988.     }
  989.     }
  990.  
  991.  
  992.     /**
  993.      * Adds a child that will appear in one of the scroll panes
  994.      * corners, if there's room.   For example with both scrollbars
  995.      * showing (on the right and bottom edges of the scrollpane) 
  996.      * the lower left corner component will be shown in the space
  997.      * between ends of the two scrollbars. Legal values for 
  998.      * the <b>key</b> are:
  999.      * <ul>
  1000.      * <li>JScrollPane.LOWER_LEFT_CORNER
  1001.      * <li>JScrollPane.LOWER_RIGHT_CORNER
  1002.      * <li>JScrollPane.UPPER_LEFT_CORNER
  1003.      * <li>JScrollPane.UPPER_RIGHT_CORNER
  1004.      * </ul>
  1005.      * <p>
  1006.      * Although "corner" isn't doesn't match any beans property
  1007.      * signature, PropertyChange events are generated with the
  1008.      * property name set to the corner key.
  1009.      * 
  1010.      * @param key identifies which corner the component will appear in
  1011.      * @param corner any component
  1012.      */
  1013.     public void setCorner(String key, Component corner) 
  1014.     {
  1015.     Component old;
  1016.     if (key.equals(LOWER_LEFT_CORNER)) {
  1017.         old = lowerLeft;
  1018.         lowerLeft = corner;
  1019.     }
  1020.     else if (key.equals(LOWER_RIGHT_CORNER)) {
  1021.         old = lowerRight;
  1022.         lowerRight = corner;
  1023.     }
  1024.     else if (key.equals(UPPER_LEFT_CORNER)) {
  1025.         old = upperLeft;
  1026.         upperLeft = corner;
  1027.     }
  1028.     else if (key.equals(UPPER_RIGHT_CORNER)) {
  1029.         old = upperRight;
  1030.         upperRight = corner;
  1031.     }
  1032.     else {
  1033.         throw new IllegalArgumentException("invalid corner key");
  1034.     }
  1035.     add(corner, key);
  1036.     firePropertyChange(key, old, corner);
  1037.     }
  1038.  
  1039.  
  1040.     /** 
  1041.      * See readObject() and writeObject() in JComponent for more 
  1042.      * information about serialization in Swing.
  1043.      */
  1044.     private void writeObject(ObjectOutputStream s) throws IOException {
  1045.         s.defaultWriteObject();
  1046.     if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  1047.         ui.installUI(this);
  1048.     }
  1049.     }
  1050.  
  1051.  
  1052.     /**
  1053.      * Returns a string representation of this JScrollPane. This method 
  1054.      * is intended to be used only for debugging purposes, and the 
  1055.      * content and format of the returned string may vary between      
  1056.      * implementations. The returned string may be empty but may not 
  1057.      * be <code>null</code>.
  1058.      * <P>
  1059.      * Overriding paramString() to provide information about the
  1060.      * specific new aspects of the JFC components.
  1061.      * 
  1062.      * @return  a string representation of this JScrollPane.
  1063.      */
  1064.     protected String paramString() {
  1065.         String viewportBorderString = (viewportBorder != null ?
  1066.                        viewportBorder.toString() : "");
  1067.         String viewportString = (viewport != null ?
  1068.                  viewport.toString() : "");
  1069.         String verticalScrollBarPolicyString;
  1070.         if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
  1071.             verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_AS_NEEDED";
  1072.         } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_NEVER) {
  1073.             verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_NEVER";
  1074.         } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
  1075.             verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_ALWAYS";
  1076.         } else verticalScrollBarPolicyString = "";
  1077.         String horizontalScrollBarPolicyString;
  1078.         if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
  1079.             horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_AS_NEEDED";
  1080.         } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
  1081.             horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_NEVER";
  1082.         } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
  1083.             horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_ALWAYS";
  1084.         } else horizontalScrollBarPolicyString = "";
  1085.         String horizontalScrollBarString = (horizontalScrollBar != null ?
  1086.                         horizontalScrollBar.toString()
  1087.                         : "");
  1088.         String verticalScrollBarString = (verticalScrollBar != null ?
  1089.                       verticalScrollBar.toString() : "");
  1090.         String columnHeaderString = (columnHeader != null ?
  1091.                      columnHeader.toString() : "");
  1092.         String rowHeaderString = (rowHeader != null ?
  1093.                   rowHeader.toString() : "");
  1094.         String lowerLeftString = (lowerLeft != null ?
  1095.                   lowerLeft.toString() : "");
  1096.         String lowerRightString = (lowerRight != null ?
  1097.                   lowerRight.toString() : "");
  1098.         String upperLeftString = (upperLeft != null ?
  1099.                   upperLeft.toString() : "");
  1100.         String upperRightString = (upperRight != null ?
  1101.                   upperRight.toString() : "");
  1102.  
  1103.         return super.paramString() +
  1104.         ",columnHeader=" + columnHeaderString +
  1105.         ",horizontalScrollBar=" + horizontalScrollBarString +
  1106.         ",horizontalScrollBarPolicy=" + horizontalScrollBarPolicyString +
  1107.         ",lowerLeft=" + lowerLeftString +
  1108.         ",lowerRight=" + lowerRightString +
  1109.         ",rowHeader=" + rowHeaderString +
  1110.         ",upperLeft=" + upperLeftString +
  1111.         ",upperRight=" + upperRightString +
  1112.         ",verticalScrollBar=" + verticalScrollBarString +
  1113.         ",verticalScrollBarPolicy=" + verticalScrollBarPolicyString +
  1114.         ",viewport=" + viewportString +
  1115.         ",viewportBorder=" + viewportBorderString;
  1116.     }
  1117.  
  1118. /////////////////
  1119. // Accessibility support
  1120. ////////////////
  1121.  
  1122.     /**
  1123.      * Get the AccessibleContext associated with this JComponent
  1124.      *
  1125.      * @return the AccessibleContext of this JComponent
  1126.      */
  1127.     public AccessibleContext getAccessibleContext() {
  1128.         if (accessibleContext == null) {
  1129.             accessibleContext = new AccessibleJScrollPane();
  1130.         }
  1131.         return accessibleContext;
  1132.     }
  1133.  
  1134.     /**
  1135.      * The class used to obtain the accessible role for this object.
  1136.      * <p>
  1137.      * <strong>Warning:</strong>
  1138.      * Serialized objects of this class will not be compatible with
  1139.      * future Swing releases.  The current serialization support is appropriate
  1140.      * for short term storage or RMI between applications running the same
  1141.      * version of Swing.  A future release of Swing will provide support for
  1142.      * long term persistence.
  1143.      */
  1144.     protected class AccessibleJScrollPane extends AccessibleJComponent 
  1145.     implements ChangeListener {
  1146.  
  1147.         protected JViewport viewPort = null;
  1148.  
  1149.         public void resetViewPort() {
  1150.             viewPort.removeChangeListener(this);
  1151.             viewPort = JScrollPane.this.getViewport();
  1152.             viewPort.addChangeListener(this);
  1153.         }
  1154.  
  1155.         /**
  1156.          * Constructor to set up listener on viewport.
  1157.          */
  1158.         public AccessibleJScrollPane() {
  1159.             super();
  1160.             if (viewPort == null) {
  1161.                viewPort = JScrollPane.this.getViewport();
  1162.             }
  1163.             viewPort.addChangeListener(this);
  1164.         }
  1165.  
  1166.         /**
  1167.          * Get the role of this object.
  1168.          *
  1169.          * @return an instance of AccessibleRole describing the role of the 
  1170.          * object
  1171.          * @see AccessibleRole
  1172.          */
  1173.         public AccessibleRole getAccessibleRole() {
  1174.             return AccessibleRole.SCROLL_PANE;
  1175.         }
  1176.  
  1177.         /**
  1178.          * Supports the change listener interface and fires property change
  1179.          */
  1180.         public void stateChanged(ChangeEvent e) {
  1181.             AccessibleContext ac = ((Accessible)JScrollPane.this).getAccessibleContext();
  1182.             if (ac != null) {
  1183.                 ac.firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, new Boolean(false), new Boolean(true));
  1184.             }
  1185.         }
  1186.     }
  1187. }
  1188.  
  1189.